import { EventEmitter } from 'events';
import Redis from 'ioredis';
import {
  AnalyticsService,
  AnalyticsConfig,
  AnalyticsCache,
  CacheConfig
} from '../types/services';
import { errorHandler } from '../utils/errorHandler';

export class AnalyticsServiceImpl implements AnalyticsService {
  private readonly redis: Redis;
  private readonly config: AnalyticsConfig;
  private readonly cacheConfig: CacheConfig;
  private preloadTimer?: NodeJS.Timeout;
  private isShuttingDown = false;

  constructor(
    redis: Redis,
    config: AnalyticsConfig,
    cacheConfig: CacheConfig
  ) {
    this.redis = redis;
    this.config = config;
    this.cacheConfig = cacheConfig;
    this.startPreloadScheduler();
  }

  // 健康检查实现
  async healthCheck(): Promise<boolean> {
    try {
      // 检查Redis连接
      await this.redis.ping();

      // 检查配置有效性
      if (!this.validateConfig()) {
        throw new Error('Invalid analytics configuration');
      }

      // 检查预加载状态
      if (!this.checkPreloadStatus()) {
        throw new Error('Preload scheduler is not running');
      }

      // 检查缓存状态
      const cacheStatus = await this.checkCacheStatus();
      if (!cacheStatus) {
        throw new Error('Cache system is not healthy');
      }

      return true;
    } catch (error) {
      errorHandler.handleError(error instanceof Error ? error : new Error('Health check failed'));
      return false;
    }
  }

  // 数据预热
  async preloadData(config: AnalyticsConfig): Promise<void> {
    try {
      if (this.isShuttingDown) {
        throw new Error('Service is shutting down');
      }

      const timeRanges = config.aggregationRules.timeRanges;
      const dimensions = config.aggregationRules.dimensions;
      const metrics = config.aggregationRules.metrics;

      const pipeline = this.redis.pipeline();

      for (const timeRange of timeRanges) {
        for (const dimension of dimensions) {
          for (const metric of metrics) {
            const cacheKey = this.buildCacheKey(timeRange, dimension, metric);
            const data = await this.calculateAnalytics(timeRange, dimension, metric);
            const cacheData: AnalyticsCache = {
              key: cacheKey,
              data,
              createdAt: new Date(),
              expiresAt: new Date(Date.now() + this.cacheConfig.ttl * 1000),
              accessCount: 0,
              lastAccessed: new Date()
            };
            
            pipeline.set(cacheKey, JSON.stringify(cacheData));
          }
        }
      }

      await pipeline.exec();
    } catch (error) {
      errorHandler.handleError(error instanceof Error ? error : new Error('Preload failed'));
      throw error;
    }
  }

  // 获取缓存的分析数据
  async getCachedAnalytics(key: string): Promise<AnalyticsCache | null> {
    try {
      if (this.isShuttingDown) {
        throw new Error('Service is shutting down');
      }

      const cached = await this.redis.get(key);
      if (!cached) {
        return null;
      }

      const cacheData: AnalyticsCache = JSON.parse(cached);
      
      // 检查缓存是否过期
      if (new Date(cacheData.expiresAt) < new Date()) {
        await this.redis.del(key);
        return null;
      }

      // 更新访问统计
      const pipeline = this.redis.pipeline();
      pipeline.hincrby('analytics:stats', key, 1);
      pipeline.hset('analytics:lastAccess', key, new Date().toISOString());
      await pipeline.exec();

      return cacheData;
    } catch (error) {
      errorHandler.handleError(error instanceof Error ? error : new Error('Cache retrieval failed'));
      return null;
    }
  }

  // 清除缓存
  async invalidateCache(pattern: string): Promise<void> {
    try {
      let cursor = '0';
      do {
        const [newCursor, keys] = await this.redis.scan(
          cursor,
          'MATCH',
          pattern,
          100
        );
        cursor = newCursor;

        if (keys.length > 0) {
          const pipeline = this.redis.pipeline();
          for (const key of keys) {
            pipeline.del(key);
            pipeline.hdel('analytics:stats', key);
            pipeline.hdel('analytics:lastAccess', key);
          }
          await pipeline.exec();
        }
      } while (cursor !== '0');
    } catch (error) {
      errorHandler.handleError(error instanceof Error ? error : new Error('Cache invalidation failed'));
    }
  }

  // 资源清理
  async cleanup(): Promise<void> {
    try {
      this.isShuttingDown = true;

      // 停止预加载调度器
      if (this.preloadTimer) {
        clearInterval(this.preloadTimer);
        this.preloadTimer = undefined;
      }

      // 清理所有缓存
      await this.clearAllCache();

      // 等待所有进行中的操作完成
      await this.waitForPendingOperations();
    } catch (error) {
      errorHandler.handleError(error instanceof Error ? error : new Error('Cleanup failed'));
      throw error;
    }
  }

  // 停止服务 - cleanup的同步版本
  stop(): void {
    void this.cleanup().catch(error => {
      errorHandler.handleError(error instanceof Error ? error : new Error('Stop failed'));
    });
  }

  // 私有辅助方法
  private startPreloadScheduler(): void {
    if (this.isShuttingDown) return;

    const interval = Math.max(
      this.config.cacheStrategy.updateFrequency * 1000,
      60000 // 最小1分钟
    );

    this.preloadTimer = setInterval(() => {
      void this.preloadData(this.config).catch(error => {
        errorHandler.handleError(error instanceof Error ? error : new Error('Preload scheduler failed'));
      });
    }, interval);
  }

  private validateConfig(): boolean {
    const { preloadThreshold, cacheStrategy, aggregationRules } = this.config;

    // 验证预加载阈值
    if (preloadThreshold <= 0) {
      return false;
    }

    // 验证缓存策略
    if (!cacheStrategy ||
        cacheStrategy.ttl <= 0 ||
        cacheStrategy.updateFrequency <= 0 ||
        (cacheStrategy.maxSize && cacheStrategy.maxSize <= 0)) {
      return false;
    }

    // 验证聚合规则
    if (!aggregationRules ||
        !aggregationRules.timeRanges.length ||
        !aggregationRules.dimensions.length ||
        !aggregationRules.metrics.length) {
      return false;
    }

    return true;
  }

  private checkPreloadStatus(): boolean {
    return !this.isShuttingDown && this.preloadTimer !== undefined;
  }

  private async checkCacheStatus(): Promise<boolean> {
    try {
      const testKey = 'healthcheck:analytics:test';
      await this.redis.set(testKey, '1', 'EX', 5);
      const value = await this.redis.get(testKey);
      await this.redis.del(testKey);
      return value === '1';
    } catch {
      return false;
    }
  }

  private async clearAllCache(): Promise<void> {
    const pattern = `${this.cacheConfig.prefix}analytics:*`;
    await this.invalidateCache(pattern);
  }

  private buildCacheKey(timeRange: string, dimension: string, metric: string): string {
    return `analytics:${timeRange}:${dimension}:${metric}`;
  }

  private async calculateAnalytics(
    timeRange: string,
    dimension: string,
    metric: string
  ): Promise<unknown> {
    // TODO: 实现具体的分析计算逻辑
    return {};
  }

  private async waitForPendingOperations(): Promise<void> {
    // TODO: 实现等待进行中操作完成的逻辑
    await new Promise(resolve => setTimeout(resolve, 1000));
  }
}
